/*
 * ====================================================================
 * Copyright (c) 2002-2018 The RapidSVN Group.  All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program (in the file GPL.txt).
 * If not, see <http://www.gnu.org/licenses/>.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://rapidsvn.tigris.org/.
 * ====================================================================
 */

// wxWidgets
#include "wx/wx.h"

// app
#include "action_event.hpp"
#include "ids.hpp"

/*
 * .h file:
 * struct
 * enum
 * int
 *
 * core definition:
 *  enum
 *
 * from:
 * to:
 * id:
 * extend info:
 *
 */
struct ActionEvent::CoreData {
public:
    wxWindow * parent;
    wxCommandEvent * event;
    int eventId;

    wxString msg;
    void * data{};

    //
    CoreData ( wxWindow * parent_, int eventId_ ) :
            parent ( parent_ ), eventId ( eventId_ )
    {
        //发送消息, wxCommandEvent, Menu Item selected
        //wxCommandEvent(wxEventType commandType = wxEVT_NULL, int winid = 0);
        event = new wxCommandEvent ( wxEVT_COMMAND_MENU_SELECTED, ACTION_EVENT );
        event->SetInt ( eventId );
    }

    ~CoreData()
    {
        delete event;
    }
};

/**
 * action worker thread
 * action容器
 * ui create the event, post it the worker thread
 *
 */
ActionEvent::ActionEvent ( wxWindow * parent, int eventId )
        :parent(parent), event(nullptr), eventId(eventId), data(nullptr)
        //: m ( nullptr )
{
    init ( parent, eventId );
}

//negative the data
ActionEvent::ActionEvent ( wxWindow * parent, int eventId, const wxString & msg )
        :parent(parent), event(nullptr), eventId(eventId), data(nullptr)
        //: m ( nullptr )
{
    init ( parent, eventId, msg );
//  m->event->SetString (msg);
}
//
ActionEvent::ActionEvent ( wxWindow * parent, int eventId, void * data )
        :parent(parent), event(nullptr), eventId(eventId), data(nullptr)
//: m ( nullptr )
{
    init ( parent, eventId, data );
//  m->event->SetClientData (data);
}

//data
//构造函数与init函数的区别？
ActionEvent::ActionEvent ( wxWindow * parent, int eventId, LogItemType type,
                           const wxString & action, const wxString & msg )
        :parent(parent), event(nullptr), eventId(eventId), data(nullptr)
        //: m ( nullptr )
{
    //event = new wxCommandEvent ( wxEVT_COMMAND_MENU_SELECTED, ACTION_EVENT );
    //event->SetInt ( eventId );
    init ( parent, eventId, type, action, msg );
//  m->event->SetString (msg);
}

ActionEvent::~ActionEvent()
{
    delete event;
    //delete m;
}

//必须选的
void ActionEvent::init ( wxWindow * _parent, int _eventId )
{
    /*
    if ( m == nullptr ) {
        m = new Data ( parent, eventId );
        //this->parent = parent;
        //this->eventId = eventId;
        //event = new wxCommandEvent ( wxEVT_COMMAND_MENU_SELECTED, ACTION_EVENT );
        //event->SetInt ( eventId );
    } else {
        //
        m->event->SetInt ( eventId );
        m->event->SetString ( wxEmptyString );
        m->event->SetClientData ( nullptr );
    }*/
    if( event== nullptr ){
        this->parent = _parent;
        this->eventId = _eventId;
        event = new wxCommandEvent ( wxEVT_COMMAND_MENU_SELECTED, ACTION_EVENT );
        event->SetInt ( _eventId );
    }else{
        this->event->SetInt( _eventId );

        this->event->SetString ( wxEmptyString );
        this->event->SetClientData ( nullptr );
    }
}

void ActionEvent::init ( wxWindow * _parent, int _eventId, const wxString & _msg )
{
    init ( _parent, _eventId );
    //m->event->SetString ( msg );
    //m->event->SetClientData ( nullptr );
    this->event->SetString ( _msg );
    this->event->SetClientData ( nullptr );
}

//pass action
//init
void ActionEvent::init ( wxWindow * _parent,
                         int _eventId,
                         LogItemType type,
                         const wxString & action, const wxString & _msg )
{
    init ( _parent, _eventId );
    wxString cat;
    cat << action << "|||" << _msg;
    //m->event->SetString ( cat );
    //m->event->SetExtraLong ( type );
    //m->event->SetClientData ( nullptr );
    this->event->SetString ( cat );
    this->event->SetExtraLong ( type );
    this->event->SetClientData ( nullptr );
}

//fill the event message
void ActionEvent::init ( wxWindow * _parent, int _eventId, void * _data )
{
    init ( _parent, _eventId );
    //m->event->SetClientData ( data );
    //m->event->SetString ( wxEmptyString );
    //
    this->event->SetClientData ( _data );
    this->event->SetString ( wxEmptyString );
}

// void // ActionEvent::SetCode (int code)
// {
//   m->event->SetInt (code);
// }

// void // ActionEvent::SetStr (wxString msg)
// {
//   m->event->SetString (msg);
// }

// void // ActionEvent::SetData (void * data)
// {
//   m->event->SetClientData (data);
// }

void ActionEvent::Post() const
{
    //??
    //wxPostEvent ( m->parent, *m->event );
    //
    wxPostEvent ( this->parent, *this->event );
}

void ActionEvent::Post ( wxWindow * parent, int event_id )
{
    //
    ActionEvent event ( parent, event_id );
    event.Post();
}

/**
 *
 */
void ActionEvent::Post ( wxWindow * parent, int event_id, const wxString & msg )
{
    ActionEvent event ( parent, event_id, msg );
    //
    event.Post();
}

void ActionEvent::Post ( wxWindow * parent, int event_id, LogItemType type,
                         const wxString & action, const wxString & msg )
{
    //
    ActionEvent event ( parent, event_id, type, action, msg );
    event.Post();
}

void ActionEvent::Post ( wxWindow * parent, int event_id, void * data )
{
    ActionEvent event ( parent, event_id, data );
    event.Post();
}

/* -----------------------------------------------------------------
 * local variables:
 * eval: (load-file "../rapidsvn-dev.el")
 * end:
 */
